//
//  BitmapCompareUtil.m
//  YHOCR
//
//  Created by 杨杨子 on 2018/7/23.
//  Copyright © 2018年 杨杨子. All rights reserved.
//

#import "BitmapCompareUtil.h"
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "PublicTool.h"
static const NSInteger SIZE = 32;
static const NSInteger SMALLER_SIZE = 8;
//#define PI 3.14159265354
double f[32][32];
double F[32][32];

@interface BitmapCompareUtil()

@end
@implementation BitmapCompareUtil
/**
 * step1
 * 将图片缩小到32*32尺寸。这一步的作用是去除图片的细节，只保留结构、明暗等基本信息，摒弃不同尺寸、比例带来的图片差异
 */
-(UIImage *)scaleBitmap:(UIImage *)image{
    UIImage *imaged = [self thumbnailWithImageWithoutScale:image size:CGSizeMake(32, 32)];//(32, 32)
    [self loadImageFinished:imaged];
    return imaged;
}

- (UIImage *)thumbnailWithImageWithoutScale:(UIImage *)image size:(CGSize)asize{//(32,32)
        UIImage *newImage = nil;
        CGSize newImageSize = asize; UIGraphicsBeginImageContextWithOptions(CGSizeMake(newImageSize.width , newImageSize.height ), NO, 0);
        
        [image drawInRect:CGRectMake(0, 0, newImageSize.width, newImageSize.height) blendMode:kCGBlendModeNormal alpha:1.0];
        newImage = UIGraphicsGetImageFromCurrentImageContext();
        if (newImage == nil) {
            NSLog(@"image ");
        }
        UIGraphicsEndImageContext();
    return newImage;
}
/**
 * step2
 * 将缩小后的图片，转为灰度
 */
-(UIImage *)convertGreyImg:(UIImage *)sourceImage{
    CGFloat width = sourceImage.size.width;
    CGFloat height = sourceImage.size.height;
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
    CGContextRef context = CGBitmapContextCreate(nil,width,height,8,0,colorSpace,kCGImageAlphaNone);
    CGColorSpaceRelease(colorSpace);
    if (context == NULL) {
        return nil;
    }
    CGContextDrawImage(context,CGRectMake(0,0, width, height), sourceImage.CGImage);
    CGImageRef grayImageRef =CGBitmapContextCreateImage(context);
    UIImage*grayImage=[UIImage imageWithCGImage:grayImageRef];
    CGContextRelease(context);
    CGImageRelease(grayImageRef);
    return grayImage;
}
/**
 * 离散余弦变换 newcc
 */

-(void)newApplyDCT{
    int N = SIZE;
    double c[SIZE];
    for (int i = 1; i < SIZE; i++) {
        c[i] = 1;
    }
    c[0] = 1 / sqrt(2.0);
    for (int u = 0; u < N; u++) {
        for (int v = 0; v < N; v++) {
            double sum = 0.0;
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    //DCT公式实现，专业术语称之为“离散余弦变换”
                    sum += cos(((2 * i + 1) / (2.0 * N)) * u * M_PI) * cos(((2 * j + 1) / (2.0 * N)) * v * M_PI) * (f[i][j]);
                }
            }
            sum *= ((c[u] * c[v]) / 4.0);
            F[u][v] = sum;
        }
    }
}
/**
 * 两张图片的消息指纹比较的方法
 *
 * @param s1 指纹1
 * @param s2 指纹2
 * @return 差异值, 越小代表越相似
 */
-(NSInteger)diffS1:(NSString *)s1 s2:(NSString *)s2{
//    char s1s[s1.length];
    NSString *ss1 = s1;
    NSString *ss2 = s2;
    NSMutableArray * s1s = [NSMutableArray array];
    for (NSInteger index = 0; index < ss1.length; index ++) {
        NSRange r = {0,1};
        NSString *twoStr = [s1 substringToIndex:1];
        s1 = [s1 stringByReplacingCharactersInRange:r withString:@""];
        [s1s addObject:twoStr];
        NSLog(@"fff:%@",s1s[index]);
    }
   ///
    NSMutableArray * s2s = [NSMutableArray array];
    for (NSInteger index = 0; index < ss2.length; index ++) {
        NSRange r = {0,1};
        NSString *twoStr = [s2 substringToIndex:1];
        s2 = [s2 stringByReplacingCharactersInRange:r withString:@""];
        [s2s addObject:twoStr];
        NSLog(@"ddd:%@",s2s[index]);
    }
   ////
    int diffNum = 0;
    for (int i = 0; i < ss1.length; i++) {
        NSString *ss1 = s1s[i];
        NSString *ss2 = s2s[i];
        if (![ss1 isEqualToString:ss2]) {
            diffNum++;
        }
    }
    NSLog(@"aavv:%d",diffNum);
    
    return diffNum;
}
/**
 * 获取图片指纹
 *
 * @param image 图片
 * @return 指纹
 */
-(NSString *)getBitmapFingerprint:(UIImage *)image{//
 
    UIImage *scaleBitmap = [self scaleBitmap:image];
   UIImage *grayBitmap = [self convertGreyImg:scaleBitmap];
    for (int x = 0; x < grayBitmap.size.width; x++) {
        for (int y = 0; y < grayBitmap.size.height; y++) {
           UIColor *color = [PublicTool colorAtPixel:CGPointMake(x, y) WithImage:grayBitmap];
            f[x][y] = [[PublicTool numberHexString:[[PublicTool hexFromUIColor:color] substringFromIndex:1]] doubleValue];
        }
    }
    //input是一个全局二维数组，省去了使用二维数组做参数yh
    /*
     *  对获取的所有像素点的RGB值进行DCT计算
     *  DCT算法是专门针对于图像压缩计算方法，
     *  如果您感兴趣，请参看：
     *  http://zh.wikipedia.org/wiki/%E7%A6%BB%E6%95%A3%E4%BD%99%E5%BC%A6%E5%8F%98%E6%8D%A2
     */
    [self newApplyDCT];
    /* 重置DCT，仅仅取压缩后的全图左上角8*8 pix的区间作为代表
     * （因为此区间代表了变化低频区域，那么低频区的差异性更客观地代表图片整体的匹配度）
     */
    double total = 0;
    for (int x = 0; x < SMALLER_SIZE; x++) {
        for (int y = 0; y < SMALLER_SIZE; y ++) {
            total += F[x][y];
        }
    }
    total -= F[0][0];
    /*
     * 计算DCT的平均值
     */
    double avg = total / (double) ((SMALLER_SIZE * SMALLER_SIZE) - 1);
    /*
     * 深度转换DCT，将结果全部组成为0/1组合队列
     */
    NSString *hash = [[NSString alloc] init];
    for (int x = 0; x < SMALLER_SIZE; x++) {
        for (int y = 0; y < SMALLER_SIZE; y++) {
            if (x != 0 && y != 0) {
               hash = [hash stringByAppendingString:[NSString stringWithFormat:@"%s",(F[x][y] > avg ? "1" : "0")]];
            }
        }
    }
    return hash;
    //[NSString stringWithFormat:@"%lu",(unsigned long)[hash hash]];
}


#pragma -mark- 保存图片的回调方法
- (void)loadImageFinished:(UIImage *)image
{
    UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), (__bridge void *)self);
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    NSLog(@"image = %@, error = %@, contextInfo = %@", image, error, contextInfo);
}

@end
